Pinvon's Blog

所见, 所闻, 所思, 所想

ES6笔记--let const

let

let 与 var 类似, 但是声明的变量只在 let 命令所在的代码块内有效, var 声明的变量在全局范围有效. 如:

{
  let a = 10;
  var b = 1;
}

a // ReferenceError: a is not defined.
b // 1

使用场景

let 命令适合在 for 循环中使用.

var a = [];
for (let i = 0; i < 10; i++) {
  a[i] = function () {
    console.log(i);
  };
}
a[6](); // 6

let 命令生成的变量, 只在本轮循环有效(这么说似乎 i 每一次都是 0 才对). 实际上, 每一轮循环的值都会被 JavaScript 引擎内部记住, i 的每一次初始化, 都在上一轮循环的基础上继续.

而如果使用 var, 则结果为:

var a = [];
for (var i = 0; i < 10; i++) {
  a[i] = function () {
    console.log(i);
  };
}
a[6](); // 10

因为 i 是全局变量, 所以 a1() 内部, 打印 i 的值时, 已经是最新的 10 了.

注意, for 循环中, 设置循环变量的部分是父作用域, 循环体是子作用域.

不存在变量提升

let 需要先声明再使用. var 则不需要.

暂时性死区(TDZ)

如果在代码块里使用了 let 命令, 则 let 命令所声明的变量就会与该代码块绑定, 不受外部影响.

如果有相同的变量名, 在代码块外部使用 var 声明, 在代码块内部使用 let 声明, 则在 let 之前不能使用该变量名, 因为这个变量已经与外部无关. 如:

var tmp = 123;

if (true) {
  tmp = 'abc'; // ReferenceError
  let tmp;
}

TDZ 的本质是, 只要一进入当前作用域, 所要使用的变量就已经存在了, 但是不可获取, 只有等到声明变量的那一行代码出现, 才可以获取和使用该变量.

const

基本用法

const 声明一个只读的常量, 一旦声明, 常量的值就不能改变.

const PI = 3.1415;
PI // 3.1415

PI = 3;
// TypeError: Assignment to constant variable.

因此, const 必须在声明的时候就初始化.

const 与 let 一样, 存在暂时性死区, 需要先声明再使用, 不能重复声明.

本质

const 的本质, 并不是变量的值不能改动, 而是变量指向的内存地址不能改动.

对于基本类型, 值就保存在变量指向的内存地址, 所以相当于常量.

对于复合类型, 变量保存的是指针, const 只能保证这个指针是固定的, 但这个变量指向的数据结构是否可变则无法控制. 可以理解成, 变量名保存的是复合类型的起始地址, const 只是保证这个起始地址不变, 而后面跟的地址保存了什么, 则不可控制.

const foo = {};

// 为 foo 添加一个属性,可以成功
foo.prop = 123;
foo.prop // 123

// 将 foo 指向另一个对象,就会报错
foo = {}; // TypeError: "foo" is read-only

Footnotes:

1

DEFINITION NOT FOUND.

Comments

使用 Disqus 评论
comments powered by Disqus